package bid

import (
	"errors"
	"fmt"
	"sync"
	"wx-api/adx-bid/cache"
	"wx-api/adx-bid/model/m_adxapp"
	"wx-api/adx-bid/model/m_adxlist"
	"wx-api/adx-bid/model/m_adxslot"
	"wx-api/adx-bid/models/bid/BidModel"
	"wx-api/adx-bid/utils"
)

func Plan(isdebug bool, sty string, req *BidModel.BidRequest, a_info *m_adxlist.AdxList, m_info *m_adxapp.AdxApp, s_info *m_adxslot.AdxSlot) (*BidModel.BidResponse, string, string, string, error) {
	if sty == "3" {
		return DspRtbAd(isdebug, sty, req, a_info, m_info, s_info)
	}
	//查询广告位对应的计划
	plan_ids := cache.CacheAdxPlanListResAdxSlotGet(sty + s_info.Uqid)
	if len(plan_ids) == 0 {
		return nil, "", "", "", errors.New("plans is empty:" + sty + s_info.Uqid)
	}
	//随机筛选出一个可用的
	plan := cache.CacheAdxPlanListMapGets(plan_ids)
	if plan == nil {
		return nil, "", "", "", errors.New("plan is empty:" + sty + s_info.Uqid)
	}
	//获取可用dsp位置
	dsp_slots := cache.PlanResDspItemsGet(plan.Uqid)
	if len(dsp_slots) == 0 {
		return nil, "", "", "", errors.New("dsp_slot is empty:" + sty + s_info.Uqid + "=" + plan.Uqid)
	}

	DspArr := []*BudgetService{}
	for _, dsp_slot := range dsp_slots {
		d_info, ok := cache.CacheChannelListMapGet(dsp_slot.DspId)
		if !ok || d_info == nil {
			continue
		}
		tmp_item := cache.GetAdxPlanItem(dsp_slot.Uqid, plan)
		if tmp_item == nil {
			continue
		}
		MSPrice := float32(tmp_item.RtbPrice)
		if MSPrice == 0 {
			MSPrice = Bprice(float32(req.GetImp()[0].GetBidfloor()), int64(tmp_item.MinPriceRate), int64(tmp_item.RetPriceRate))
		}
		DspArr = append(DspArr, &BudgetService{
			Req:      req,
			Adx:      a_info,
			Media:    m_info,
			Slot:     s_info,
			Plan:     plan,
			PlanItem: tmp_item,
			Dsp:      d_info,
			Pos:      dsp_slot,
			IsRtb:    true,
			Syst:     sty,
			MdPrice:  float32(req.GetImp()[0].GetBidfloor()), //媒体底价
			MFPrice:  0,                                      //媒体成交价
			MSPrice:  MSPrice,                                //媒体发送给上游出价
			DdPrice:  0,                                      //上游出价
			DFPrice:  0,                                      //上游成交价
		})
	}

	dn := len(DspArr)
	if dn == 1 {
		//只有一个，直接处理
		DspBudget(sty, DspArr[0])
	} else {
		//有多个，并发处理
		wg := new(sync.WaitGroup)
		wg.Add(dn)
		for j := 0; j < dn; j++ {
			go func(p *BudgetService) {
				DspBudget(sty, p)
				wg.Done()
			}(DspArr[j])
		}
	}
	//返回的广告开始竞价
	buditem, err := SelResArr(DspArr)
	if err != nil {
		return nil, "", "", "", errors.New("DspArr is empty:" + err.Error())
	}
	buditem.Syst = sty
	//上报链接生成
	GetTrackUrls(buditem)
	//是否给下游返回价格,待定
	//重组广告
	bidres := &BidModel.BidResponse{
		Id: func(a string) string {
			if a != "" {
				return a
			}
			return req.GetBidId()
		}(req.GetId()),
		Seatbid: []*BidModel.BidResponse_SeatBid{
			{
				Bid: []*BidModel.BidResponse_SeatBid_Bid{
					buditem.ResBid,
				},
			},
		},
		Bidid: req.GetBidId(),
	}
	return bidres, "", "", "", nil
}

func SelResArr(sarr []*BudgetService) (*BudgetService, error) {
	ret_arr := []*BudgetService{}
	Q_arr := []*BudgetService{}
	for _, v := range sarr {
		if v.Err != nil {
			fmt.Println("sel err:", v.Err)
		}
		if v.ResBid == nil {
			continue
		}
		if len(v.ResBid.GetImgs()) == 0 && v.ResBid.GetVideo() == nil { //无素材
			continue
		}
		if v.PlanItem.Flag {
			Q_arr = append(Q_arr, v)
		}
		ret_arr = append(ret_arr, v)
	}
	//优先返回
	q_a := len(Q_arr)
	if q_a > 0 {
		if q_a == 1 {
			return Q_arr[0], nil
		}
		//随机一个返回
		q_id := utils.RandInt64(0, int64(q_a-1))
		return Q_arr[q_id], nil
	}
	//随机返回一个,权重筛选暂时忽略
	w_a := len(ret_arr)
	if w_a > 0 {
		if w_a == 1 {
			return ret_arr[0], nil
		}
		w_id := utils.RandInt64(0, int64(w_a-1))
		return ret_arr[w_id], nil
	}
	return nil, errors.New("SelResArr is empty")
}
